package handler

import (
	"context"
	"encoding/json"
	"github.com/astaxie/beego/logs"
	"github.com/astaxie/beego/orm"
	"github.com/garyburd/redigo/redis"
	"ihome/models"
	"ihome/utils"
	"strconv"

	"github.com/micro/go-micro/util/log"

	addHouse "ihome/proto/addHouse"
)

type AddHouse struct{}

func (e *AddHouse) SrvAddHouse(ctx context.Context, req *addHouse.Request, rsp *addHouse.Response) error {
	logs.Info("添加房源 AddHouses /api/v1.0/houses")

	rsp.Code = utils.RecodeOk
	rsp.Msg = utils.RecodeText(rsp.Code)

	bm, err := utils.NewCache()
	if err != nil {
		logs.Info("redis连接失败", err)
		rsp.Code = utils.RecodeDberr
		rsp.Msg = utils.RecodeText(rsp.Code)
		return nil
	}
	sessionId := req.SessionId
	userIdObj := bm.Get(sessionId + "user_id")
	userId, _ := redis.Int(userIdObj, nil)

	var request = make(map[string]interface{})
	json.Unmarshal(req.Body, &request)

	price, _ := strconv.Atoi(request["price"].(string))
	roomCount, _ := strconv.Atoi(request["room_count"].(string))
	acreage, _ := strconv.Atoi(request["acreage"].(string))
	capacity, _ := strconv.Atoi(request["capacity"].(string))
	deposit, _ := strconv.Atoi(request["deposit"].(string))
	minDays, _ := strconv.Atoi(request["min_days"].(string))
	maxDays, _ := strconv.Atoi(request["max_days"].(string))
	areaId, _ := strconv.Atoi(request["area_id"].(string))
	area := models.Area{Id: areaId}
	var facilitys []*models.Facility
	for _, value := range request["facility"].([]interface{}) {
		fid, _ := strconv.Atoi(value.(string))
		ftmp := &models.Facility{Id: fid}
		facilitys = append(facilitys, ftmp)
	}
	user := models.User{Id: userId}
	house := models.House{
		Title: request["title"].(string),
		Price: price*100,
		Address: request["address"].(string),
		Room_count: roomCount,
		Acreage: acreage,
		Unit: request["unit"].(string),
		Capacity: capacity,
		Beds: request["beds"].(string),
		Deposit: deposit,
		Min_days: minDays,
		Max_days: maxDays,
		Area: &area,
		User: &user,
	}

	o := orm.NewOrm()
	houseId, err := o.Insert(&house)
	if err != nil {
		logs.Info("插入数据失败", err)
		rsp.Code = utils.RecodeDberr
		rsp.Msg = utils.RecodeText(rsp.Code)
		return nil
	}

	m2m := o.QueryM2M(&house, "Facilities")
	_, err = m2m.Add(facilitys)
	if err != nil {
		logs.Info("房屋设施多对多插入数据失败", err)
		rsp.Code = utils.RecodeDberr
		rsp.Msg = utils.RecodeText(rsp.Code)
		return nil
	}

	rsp.HouseId = strconv.Itoa(int(houseId))

	return nil
}

// Stream is a server side stream handler called via client.Stream or the generated client code
func (e *AddHouse) Stream(ctx context.Context, req *addHouse.StreamingRequest, stream addHouse.AddHouse_StreamStream) error {
	log.Logf("Received AddHouse.Stream request with count: %d", req.Count)

	for i := 0; i < int(req.Count); i++ {
		log.Logf("Responding: %d", i)
		if err := stream.Send(&addHouse.StreamingResponse{
			Count: int64(i),
		}); err != nil {
			return err
		}
	}

	return nil
}

// PingPong is a bidirectional stream handler called via client.Stream or the generated client code
func (e *AddHouse) PingPong(ctx context.Context, stream addHouse.AddHouse_PingPongStream) error {
	for {
		req, err := stream.Recv()
		if err != nil {
			return err
		}
		log.Logf("Got ping %v", req.Stroke)
		if err := stream.Send(&addHouse.Pong{Stroke: req.Stroke}); err != nil {
			return err
		}
	}
}
